package com.green.common.weibo4j.microblog;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;

import com.green.common.weibo4j.Timeline;
import com.green.common.weibo4j.Users;
import com.green.common.weibo4j.Weibo;
import com.green.common.weibo4j.microblog.models.Author;
import com.green.common.weibo4j.microblog.models.SingleMessage;
import com.green.common.weibo4j.model.Paging;
import com.green.common.weibo4j.model.Status;
import com.green.common.weibo4j.model.StatusWapper;
import com.green.common.weibo4j.model.User;
import com.green.common.weibo4j.model.WeiboException;
import com.green.common.weibo4j.org.json.JSONArray;

public class MicroBlogBlender {

	private static Cache cache;

	/** 身份认证 **/
	private static String accessToken;
	private static String uid;

	/** 缓存ID **/
	private static String BASIC_INFO_ID = "basicInfoId";
	private static String MICRO_ID_PREFIX = "microbId_";


	/** basic key **/
	public final static String USERNAME = "userName";
	public final static String LOCATION = "location";
	public final static String PSNIMG = "psnImg";
	public final static String COUNTS = "counts";

	/**constant**/
	private final static int COUNT_PER = 20;

	private static int NEXT_PAGE = 1;

	private static String KEYWORD = "#狼真的来了#";// "#Q房真的来了#";

	private static Properties prop = new Properties();

	static{
		try {
			prop.load(Thread.currentThread().getContextClassLoader()
					.getResourceAsStream("microblog_config.properties"));
			accessToken = (String) prop.get("access_token");
			uid = (String) prop.get("mb_uid");
			KEYWORD = (String) prop.get("keyword");
		} catch (Exception e) {
			accessToken = "2.0062GOuB0pQw3G43e05eb7746TuGZD";
			uid = "1746968631";
		}

		CacheManager manager = CacheManager.create(MicroBlogBlender.class
				.getClassLoader().getResourceAsStream("ehcache.xml"));
		cache = manager.getCache("microBlogCache");
	}

	public MicroBlogBlender(){

	}

	@SuppressWarnings("unchecked")
	public static Map<String, Object> getBasicInfo() {
		Element e = cache.get(BASIC_INFO_ID);
		if (e == null) {
			e = new Element(BASIC_INFO_ID, queryBlogOwnerInfo());
			cache.put(e);
		}
		return (Map<String, Object>) e.getObjectValue();
	}


	public static CacheBox getMessages(int numOrder) {
		Element e = cache.get(MICRO_ID_PREFIX + numOrder);
		if (e == null) {
			e = new Element(MICRO_ID_PREFIX + numOrder, querySpecialMessage());
			cache.put(e);
		}

		return (CacheBox) e.getObjectValue();
	}

	private static Map<String, Object> queryBlogOwnerInfo() {
		Weibo weibo = new Weibo();
		weibo.setToken(accessToken);
		Users um = new Users();
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			User user = um.showUserById(uid);
			map.put(USERNAME, user.getName());
			map.put(LOCATION, user.getLocation());
			map.put(PSNIMG, user.getProfileImageUrl());
			JSONArray counts = um.getUserCount(uid);
			map.put(COUNTS, counts);
			return map;
		} catch (WeiboException e) {
			e.printStackTrace();
			return null;
		}
	}


	private static CacheBox querySpecialMessage() {
		List<SingleMessage> retMessage = new ArrayList<SingleMessage>();
		boolean toEnd = false;
		while (retMessage.size() < 10) {
			List<SingleMessage> navtiveMessages = packageMessage(querySpecifiedPagNumMessage(NEXT_PAGE));
			if (CollectionUtils.isEmpty(navtiveMessages)) {
				NEXT_PAGE = 1;
				toEnd = true;
				break;
			}
			NEXT_PAGE++;
			for (SingleMessage sm : navtiveMessages) {
				if (sm.getText().startsWith(KEYWORD)) {
					retMessage.addAll(packageMessage(
							queryRepostMessage(sm.getId()), KEYWORD));
					sm.setText(searchKeyPackage(sm.getText()));
					retMessage.add(sm);
				}
			}
		}
		return new CacheBox(retMessage, toEnd);
	}

	private static List<SingleMessage> packageMessage(StatusWapper statusWapper) {
		return packageMessage(statusWapper, null);
	}
	/**
	 * 包装为世华消息
	 *
	 * @author Lineshow
	 * @since 2012-6-19
	 * @param status
	 * @return
	 */
	private static List<SingleMessage> packageMessage(
			StatusWapper statusWapper, String keyWord) {
		if (statusWapper == null) {
			return  new ArrayList<SingleMessage>();
		}
		List<Status> statuses = statusWapper.getStatuses();
		List<SingleMessage> microBMessages = new ArrayList<SingleMessage>();
		for (Status status : statuses) {
			SingleMessage singleMessage = new SingleMessage();
			if (StringUtils.isNotBlank(status.getText())) {
				singleMessage.setText(textEmbelish(status.getText()));
			} else {
				singleMessage.setText(status.getText());
			}
			if (StringUtils.isNotBlank(keyWord)) {
				singleMessage.setText(searchKeyPackage(keyWord)
						+ singleMessage.getText());
			}

			singleMessage.setId(status.getId());
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			singleMessage.setCreateAt(sdf.format(status.getCreatedAt()));
			singleMessage.setCommentCount(status.getCommentsCount());
			singleMessage.setTransmitCount(status.getRepostsCount());
			singleMessage.setSmallPic(status.getThumbnailPic());
			singleMessage.setMiddlePic(status.getBmiddlePic());
			singleMessage.setOriginalPic(status.getOriginalPic());
			if (status.getRetweetedStatus() != null) { // 假如存在转发微博
				Status repostStatus = status.getRetweetedStatus();
				SingleMessage repostMessage = new SingleMessage();
				singleMessage.setIsTransmit(1);
				Author createBy = new Author();
				if (repostStatus.getUser() != null) {
					createBy.setName(repostStatus.getUser().getScreenName());
					createBy.setProfilePic(repostStatus.getUser()
							.getProfileImageUrl());
					repostMessage.setCreateBy(createBy);
				}

				repostMessage.setId(repostStatus.getId());
				repostMessage.setText(repostStatus.getText());
				repostMessage.setSmallPic(repostStatus.getThumbnailPic());
				repostMessage.setMiddlePic(repostStatus.getBmiddlePic());
				repostMessage.setOriginalPic(repostStatus.getOriginalPic());
				repostMessage.setCommentCount(repostStatus.getCommentsCount());
				repostMessage.setTransmitCount(repostStatus.getRepostsCount());
				singleMessage.setTransmintMessage(repostMessage);
			}
			microBMessages.add(singleMessage);
		}
		return microBMessages;
	}

	/**
	 * 查询用户发表微博
	 *
	 * @author Lineshow
	 * @since 2012-6-19
	 * @param nextPage
	 * @return
	 */
	private static StatusWapper querySpecifiedPagNumMessage(int nextPage) {
		Weibo weibo = new Weibo();
		weibo.setToken(accessToken);
		Timeline tm = new Timeline();
		new HashMap<String, Object>();
		try {
			StatusWapper statusWapper = tm.getUserTimelineByUid(uid,
					new Paging(nextPage, COUNT_PER), 0, 0);
			return statusWapper;
		} catch (WeiboException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 根据MID查询该微博的转发微博
	 *
	 * @author Lineshow
	 * @since 2012-6-19
	 * @param mid
	 * @return
	 */
	private static StatusWapper queryRepostMessage(String mid) {
		Weibo weibo = new Weibo();
		weibo.setToken(accessToken);
		Timeline tm = new Timeline();
		new HashMap<String, Object>();
		try {
			StatusWapper statusWapper = tm.getRepostTimeline(mid);
			return statusWapper;
		} catch (WeiboException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * embelish text via some way
	 *
	 * @author Lineshow
	 * @since 2012-6-5
	 * @param text
	 * @return
	 */
	private static String textEmbelish(String text) {
		// wrap url in text with <a> via regular expression

		Pattern pattern = null;
		Matcher matcher = null;
		pattern = Pattern.compile("(http://[^\\s\\(]*)",
				Pattern.CASE_INSENSITIVE);
		matcher = pattern.matcher(text);
		text = matcher
				.replaceAll("<a target='_blank' href='$1' style='color:#0078B6;'>$1</a>");
		return text;
	}

	private static String searchKeyPackage(String text) {
		Pattern pattern = null;
		Matcher matcher = null;
		pattern = Pattern.compile("(#(.*)#)");
		matcher = pattern.matcher(text);
		text = matcher
				.replaceAll("<a href='http://s.weibo.com/weibo/$2'>$1</a>");
		return text;
	}

	public static void main(String[] args) {

		MicroBlogBlender.NEXT_PAGE = 1;
		CacheBox messages = MicroBlogBlender.getMessages(1);
		for (SingleMessage message : messages.getMessages()) {
			System.out.println(message.getText());
		}
		messages = MicroBlogBlender.getMessages(1);
		for (SingleMessage message : messages.getMessages()) {
			System.out.println(message.getText());
		}

	}

	public static class CacheBox implements Serializable {
		private List<SingleMessage> messages;
		private boolean toEnd;

		CacheBox() {

		}
		CacheBox(List<SingleMessage> messages, boolean toEnd) {
			this.messages = messages;
			this.toEnd = toEnd;
		}

		public List<SingleMessage> getMessages() {
			return messages;
		}

		public void setMessages(List<SingleMessage> messages) {
			this.messages = messages;
		}

		public boolean getToEnd() {
			return toEnd;
		}

		public void setToEnd(boolean toEnd) {
			this.toEnd = toEnd;
		}


	}

}
